<template>
  <div class="z-tree" :view-id="gaibian">
    <div class="z-tree-node" :key="datas.id">
      <div class="z-tree-content" v-on:click="checkSelf(datas)" :style="{ 'padding-left': (datas[childprops.lv]) * 16 + 'px' }" :class="{'active':onedefault == datas.id}">
        <i class="z-tree-icon iconfont" :class="{'icon-tianjia':!datas.showChild,'icon-jianqu':datas.showChild}" v-if="datas[childprops.children]" v-on:click.stop="showChildren(datas)"></i>
        <i class="z-none" v-if="!datas[childprops.children]"></i>
        <span v-if='!multiple' class="z-tree-node-text">
          {{datas[childprops.name]}}
        </span>
        <div class="z-mulbox" v-else>
          <div class="z-mask"></div>
          <el-checkbox class="z-check" :label="datas.id" v-model="curdefult">
            {{datas[childprops.name]}}
          </el-checkbox>
        </div>
      </div>
      <transition mode="out-in">
        <div class="z-tree-node-children" v-show="datas.showChild">
          <!-- <div class="z-tree-node">  :style="{ 'padding-left': (datas.lv) * 16 + 'px' }" 
                    <div class="z-tree-content">
                        <span class="z-tree-icon">+</span>
                        <span class="z-tree-node-text">
                            2级1
                        </span>
                    </div>
                </div> -->

          <z-tree v-for="item in datas[childprops.children]" :key="item.id" :datas="item" :childprops="childprops" :showLv="showLv" :defaults="onedefault" :arrdefaults='curdefult' :names="namearrs" :multiple="multiple" v-on:curcheck="curCheck" v-on:namearr="namearr"></z-tree>
        </div>
      </transition>
    </div>
  </div>
</template>

<script>
export default {
  name: "zTree",
  props: {
    datas: {
      type: Object,
      defautl: {}
    },
    openlv: {
      type: String
    },
    showLv: {
      type: Number
    },
    defaults: {},
    arrdefaults: {
      type: Array
    },
    multiple: {
      type: Boolean
    },
    childprops: {
      type: Object
    },
    names:{
      type:Array
    }
  },
  data() {
    return {
      showChild: false,
      active: 0,
      curdefult: [],
      onedefault: "",
      namearrs:[]
    };
  },
  computed: {
    gaibian() {
      this.curdefult = this.arrdefaults;
      this.onedefault = this.defaults;
    }
  },
  created() {
    
    
    let childprops = this.childprops;
    //默认展开1级
    if (this.datas[childprops.lv] == 0) {
      this.$set(this.datas, "showChild", true);
    }
    //默认展开2级
    if (this.datas[childprops.lv] == this.showLv) {
      this.$set(this.datas, "showChild", true);
    }

    //判断是多选还是单选
    if (this.multiple) {
      if (this.arrdefaults) {
        //判断
        let data = this.arrdefaults;
        this.curdefult = data;
        //把默认选中项的name抛出
        this.namearrs = this.names
        let ischeck = this.arrdefaults.findIndex(item => item == this.datas.id);

        if (ischeck !== -1) {
          let arr = this.namearrs;
          arr.push(this.datas[childprops.name]);
          console.log(this.namearrs,'ddddddddddd')
          this.namearrs = arr;
          this.$emit("namearr", arr);
        }
      }
    } else {
      if (this.defaults == this.datas.id + "") {
        this.$emit("curcheck", this.datas);
      }
    }
  },

  methods: {
    showChildren(item) {
      let obj = this.datas;
      if (item.showChild) {
        this.$set(item, "showChild", false);
      } else {
        this.$set(item, "showChild", true);
      }
    },
    //点击选中
    checkSelf(val) {
      let childprops = this.childprops;
      if (this.multiple) {
        //如果是多选
        let arr = this.curdefult;
        let have = arr.findIndex(item => item == val.id);
        let namearrs = this.namearrs; //当前选中name的数组
        console.log(namearrs)
        let havename = namearrs.findIndex(item => item == val[childprops.name]);
        console.log(havename)
        if (have !== -1) {
          //如果是已经选中的项 取消选择 在数组里删除对应的项
          arr.splice(have, 1);

          if (val[childprops.children] instanceof Array) {
            //如果有子集 则把子集的项取消选择 在数组删除对应的项
            let haveid = this.maparr(val[childprops.children]); //获取所有子集的id

            haveid.map(function(obj, index) {
              //遍历 删除数组对应的id
              if (arr.findIndex(item => item == obj) !== -1) {
                arr.splice(arr.findIndex(item => item == obj), 1);
              }
            });
          }
        } else {
          //如果未选择项 选择并在数组内追加
          if (val[childprops.children] instanceof Array) {
            //如果children是数组 则把子集的项追加到数组
            let haveid = this.maparr(val[childprops.children]); //获取所有子集的id的数组

            arr = this.uq(arr, haveid); //合并数组
            arr.push(val.id); //追加
          } else {
            arr.push(val.id); //追加
           
          }
        }
        //name数组判断
        if (havename !== -1) {
          namearrs.splice(havename, 1);
          if (val[childprops.children] instanceof Array) {
            let names = this.mapname(val[childprops.children]); //获取所有子集name文字的数组
            names.map(function(obj, index) {
              let nums  =namearrs.findIndex(item => item == obj) 
              //遍历 删除数组对应的id
              if ( nums!== -1) {
                namearrs.splice(nums, 1);
              }
            });
            console.log(namearrs)
            console.log('删除')
          }
        } else {
          if (val[childprops.children] instanceof Array) {
            let names = this.mapname(val[childprops.children]); //获取所有子集name文字的数组
            namearrs.push(val[childprops.name]); //追加name
            namearrs = this.nameuq(namearrs, names); //合并数组
          } else {
            namearrs.push(val[childprops.name]); //追加name
          }
        }
        console.log(namearrs)
        this.namearrs = namearrs;
        this.curdefult = arr; //设定v-model的值为改变后数组
        this.$emit("curcheck", arr); //向上提交
        this.$emit("namearr", namearrs); //向上提交
      } else {
        this.onedefault = val.id;
        this.active = val.id;
        this.$emit("curcheck", val);
      }
    },
    //遍历children返回id
    maparr(data) {
      let childprops = this.childprops;
      let newarr = [];
      function searchs(data) {
        data.map(item => {
          newarr.push(item.id);
          if (
            item[childprops.children] &&
            item[childprops.children].length > 0
          ) {
            searchs(item[childprops.children]);
          }
        });
      }
      searchs(data);

      return newarr;
    },
    //遍历children返回name文字
    mapname(data) {
      let childprops = this.childprops;
      let newarr = [];
      function searchs(data) {
        data.map(item => {
          newarr.push(item[childprops.name]);
          if (
            item[childprops.children] &&
            item[childprops.children].length > 0
          ) {
            searchs(item[childprops.children]);
          }
        });
      }
      searchs(data);

      return newarr;
    },
    //去重合并
    uq(array, array1) {
      //将array数组转换成set对象
      let setObj = new Set(array);
      //循环数组array1，并将值通过add插入set对象中,此时重复数据并不会插入其中
      for (let i = 0; i < array1.length; i++) {
        setObj.add(array1[i]);
      }
      //使用Array.from()方法将set对象转换成数组，并使用sort()方法排序
      return Array.from(setObj).sort();
    },
    //去重合并 不排序
    nameuq(array, array1) {
      //将array数组转换成set对象
      let setObj = new Set(array);
      //循环数组array1，并将值通过add插入set对象中,此时重复数据并不会插入其中
      for (let i = 0; i < array1.length; i++) {
        setObj.add(array1[i]);
      }
      //使用Array.from()方法将set对象转换成数组，并使用sort()方法排序
      return Array.from(setObj);
    },
    //当前选中
    curCheck(val) {
      if (this.multiple) {
        //多选
        let arr = val;

        this.curdefult = val;
        this.$emit("curcheck", val);
      } else {
        this.onedefault = val.id;
        this.$emit("curcheck", val);
      }
    },
    //当前选中的name
    namearr(val) {
      let arr = this.namearrs;
      console.log(arr)
      arr = this.nameuq(arr, val);
       console.log(arr)
      this.namearrs = arr;
      this.$emit("namearr", arr);
    }
  }
};
</script>
<style lang="scss" scoped>
.z-tree {
  width: 100%;
  .z-tree-node {
    // padding:0 5px;
    .z-tree-content {
      font-size: 13px;
      color: #606266;
      cursor: pointer;
      padding: 0 5px;
      height: 28px;
      line-height: 28px;
      position: relative;
      .z-tree-icon {
        font-size: 14px;
        font-style: inherit;
        cursor: default;
        padding: 0 8px;
        height: 28px;
        line-height: 28px;
      }
      .z-tree-node-text {
        padding-left: 0px;
        line-height: 28px;
        display: inline-block;
      }
    }

    .z-tree-content:hover {
      background-color: #f5f7fa;
    }
    .active {
      color: #409eff;
      font-weight: 700;
      background-color: #f5f7fa;
      .z-tree-icon {
        color: #606266;
        font-weight: normal;
      }
    }
    .active:hover {
      background-color: #f5f7fa;
    }
  }
}
.z-none {
  color: transparent;
  width: 30px;
  height: 0px;
  display: inline-block;
}
.z-mulbox {
  display: inline-block;
  position: relative;
}
.z-mask {
  position: absolute;
  z-index: 2;
  width: 100%;
  height: 28px;
}
.z-check {
  position: relative;
  z-index: 1;
}
.z-check.is-checked .el-checkbox__label {
  color: #409eff !important;
}
</style>
